package com.lysh.aliHttp;

import com.lysh.aliHttp.common.auth.RequestSigner;
import com.lysh.aliHttp.common.enums.Protocol;
import com.lysh.aliHttp.common.exception.ClientException;
import com.lysh.aliHttp.utils.ResourceManager;
import com.lysh.aliHttp.utils.VersionInfoUtils;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author liyishan
 * @date 2023/5/5 09:15
 * @apiNote
 */

public class ClientConfiguration {
    public static final String DEFAULT_USER_AGENT = VersionInfoUtils.getDefaultUserAgent();
    public static final int DEFAULT_MAX_RETRIES = 3;
    public static final int DEFAULT_CONNECTION_REQUEST_TIMEOUT = -1;
    public static final int DEFAULT_CONNECTION_TIMEOUT = 50000;
    public static final int DEFAULT_SOCKET_TIMEOUT = 50000;
    public static final int DEFAULT_MAX_CONNECTIONS = 1024;
    public static final long DEFAULT_CONNECTION_TTL = -1L;
    public static final long DEFAULT_IDLE_CONNECTION_TIME = 60000L;
    public static final int DEFAULT_VALIDATE_AFTER_INACTIVITY = 2000;
    public static final int DEFAULT_THREAD_POOL_WAIT_TIME = 60000;
    public static final int DEFAULT_REQUEST_TIMEOUT = 300000;
    public static final long DEFAULT_SLOW_REQUESTS_THRESHOLD = 300000L;
    public static final boolean DEFAULT_USE_REAPER = true;
    public static final String DEFAULT_CNAME_EXCLUDE_LIST = "aliyuncs.com,aliyun-inc.com,aliyun.com";
    protected String userAgent;
    protected int maxErrorRetry;
    protected int connectionRequestTimeout;
    protected int connectionTimeout;
    protected int socketTimeout;
    protected int maxConnections;
    protected long connectionTTL;
    protected boolean useReaper;
    protected long idleConnectionTime;
    protected Protocol protocol;
    protected String proxyHost;
    protected int proxyPort;
    protected String proxyUsername;
    protected String proxyPassword;
    protected String proxyDomain;
    protected String proxyWorkstation;
    protected boolean supportCname;
    protected List<String> cnameExcludeList;
    protected Lock rlock;
    protected boolean sldEnabled;
    protected int requestTimeout;
    protected boolean requestTimeoutEnabled;
    protected long slowRequestsThreshold;
    protected Map<String, String> defaultHeaders;
    protected boolean crcCheckEnabled;
    protected List<RequestSigner> signerHandlers;

    public ClientConfiguration() {
        this.userAgent = DEFAULT_USER_AGENT;
        this.maxErrorRetry = 3;
        this.connectionRequestTimeout = -1;
        this.connectionTimeout = 50000;
        this.socketTimeout = 50000;
        this.maxConnections = 1024;
        this.connectionTTL = -1L;
        this.useReaper = true;
        this.idleConnectionTime = 60000L;
        this.protocol = Protocol.HTTP;
        this.proxyHost = null;
        this.proxyPort = -1;
        this.proxyUsername = null;
        this.proxyPassword = null;
        this.proxyDomain = null;
        this.proxyWorkstation = null;
        this.supportCname = true;
        this.cnameExcludeList = new ArrayList();
        this.rlock = new ReentrantLock();
        this.sldEnabled = false;
        this.requestTimeout = 300000;
        this.requestTimeoutEnabled = false;
        this.slowRequestsThreshold = 300000L;
        this.defaultHeaders = new LinkedHashMap();
        this.crcCheckEnabled = true;
        this.signerHandlers = new LinkedList();
    }

    public String getUserAgent() {
        return this.userAgent;
    }

    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    public String getProxyHost() {
        return this.proxyHost;
    }

    public void setProxyHost(String proxyHost) {
        this.proxyHost = proxyHost;
    }

    public int getProxyPort() {
        return this.proxyPort;
    }

    public void setProxyPort(int proxyPort) throws ClientException {
        if (proxyPort <= 0) {
            throw new ClientException(ResourceManager.getInstance("common").getString("ParameterIsInvalid"), (Throwable)null);
        } else {
            this.proxyPort = proxyPort;
        }
    }

    public String getProxyUsername() {
        return this.proxyUsername;
    }

    public void setProxyUsername(String proxyUsername) {
        this.proxyUsername = proxyUsername;
    }

    public String getProxyPassword() {
        return this.proxyPassword;
    }

    public void setProxyPassword(String proxyPassword) {
        this.proxyPassword = proxyPassword;
    }

    public String getProxyDomain() {
        return this.proxyDomain;
    }

    public void setProxyDomain(String proxyDomain) {
        this.proxyDomain = proxyDomain;
    }

    public String getProxyWorkstation() {
        return this.proxyWorkstation;
    }

    public void setProxyWorkstation(String proxyWorkstation) {
        this.proxyWorkstation = proxyWorkstation;
    }

    public int getMaxConnections() {
        return this.maxConnections;
    }

    public void setMaxConnections(int maxConnections) {
        this.maxConnections = maxConnections;
    }

    public int getSocketTimeout() {
        return this.socketTimeout;
    }

    public void setSocketTimeout(int socketTimeout) {
        this.socketTimeout = socketTimeout;
    }

    public int getConnectionTimeout() {
        return this.connectionTimeout;
    }

    public void setConnectionTimeout(int connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public int getConnectionRequestTimeout() {
        return this.connectionRequestTimeout;
    }

    public void setConnectionRequestTimeout(int connectionRequestTimeout) {
        this.connectionRequestTimeout = connectionRequestTimeout;
    }

    public int getMaxErrorRetry() {
        return this.maxErrorRetry;
    }

    public void setMaxErrorRetry(int maxErrorRetry) {
        this.maxErrorRetry = maxErrorRetry;
    }

    public long getConnectionTTL() {
        return this.connectionTTL;
    }

    public void setConnectionTTL(long connectionTTL) {
        this.connectionTTL = connectionTTL;
    }

    public boolean isUseReaper() {
        return this.useReaper;
    }

    public void setUseReaper(boolean useReaper) {
        this.useReaper = useReaper;
    }

    public long getIdleConnectionTime() {
        return this.idleConnectionTime;
    }

    public void setIdleConnectionTime(long idleConnectionTime) {
        this.idleConnectionTime = idleConnectionTime;
    }

    public Protocol getProtocol() {
        return this.protocol;
    }

    public void setProtocol(Protocol protocol) {
        this.protocol = protocol;
    }

    public List<String> getCnameExcludeList() {
        if (this.cnameExcludeList.size() == 0) {
            this.rlock.lock();
            if (this.cnameExcludeList.size() == 0) {
                AppendDefaultExcludeList(this.cnameExcludeList);
            }

            this.rlock.unlock();
        }

        return Collections.unmodifiableList(this.cnameExcludeList);
    }

    public void setCnameExcludeList(List<String> cnameExcludeList) {
        if (cnameExcludeList == null) {
            throw new IllegalArgumentException("cname exclude list should not be null.");
        } else {
            this.cnameExcludeList.clear();
            Iterator i$ = cnameExcludeList.iterator();

            while(i$.hasNext()) {
                String excl = (String)i$.next();
                if (!excl.trim().isEmpty()) {
                    this.cnameExcludeList.add(excl);
                }
            }

            AppendDefaultExcludeList(this.cnameExcludeList);
        }
    }

    private static void AppendDefaultExcludeList(List<String> excludeList) {
        String[] excludes = "aliyuncs.com,aliyun-inc.com,aliyun.com".split(",");
        String[] arr$ = excludes;
        int len$ = excludes.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            String excl = arr$[i$];
            if (!excl.trim().isEmpty() && !excludeList.contains(excl)) {
                excludeList.add(excl.trim().toLowerCase());
            }
        }

    }

    public boolean isSupportCname() {
        return this.supportCname;
    }

    public ClientConfiguration setSupportCname(boolean supportCname) {
        this.supportCname = supportCname;
        return this;
    }

    public boolean isSLDEnabled() {
        return this.sldEnabled;
    }

    public ClientConfiguration setSLDEnabled(boolean enabled) {
        this.sldEnabled = enabled;
        return this;
    }

    public int getValidateAfterInactivity() {
        return 2000;
    }

    public boolean isRequestTimeoutEnabled() {
        return this.requestTimeoutEnabled;
    }

    public void setRequestTimeoutEnabled(boolean requestTimeoutEnabled) {
        this.requestTimeoutEnabled = requestTimeoutEnabled;
    }

    public void setRequestTimeout(int requestTimeout) {
        this.requestTimeout = requestTimeout;
    }

    public int getRequestTimeout() {
        return this.requestTimeout;
    }

    public long getSlowRequestsThreshold() {
        return this.slowRequestsThreshold;
    }

    public void setSlowRequestsThreshold(long slowRequestsThreshold) {
        this.slowRequestsThreshold = slowRequestsThreshold;
    }

    public Map<String, String> getDefaultHeaders() {
        return this.defaultHeaders;
    }

    public void setDefaultHeaders(Map<String, String> defaultHeaders) {
        this.defaultHeaders = defaultHeaders;
    }

    public void addDefaultHeader(String key, String value) {
        this.defaultHeaders.put(key, value);
    }

    public boolean isCrcCheckEnabled() {
        return this.crcCheckEnabled;
    }

    public void setCrcCheckEnabled(boolean crcCheckEnabled) {
        this.crcCheckEnabled = crcCheckEnabled;
    }

    public List<RequestSigner> getSignerHandlers() {
        return this.signerHandlers;
    }

    public void setSignerHandlers(List<RequestSigner> signerHandlers) {
        if (signerHandlers != null) {
            this.signerHandlers.clear();
            Iterator i$ = signerHandlers.iterator();

            while(i$.hasNext()) {
                RequestSigner signer = (RequestSigner)i$.next();
                if (signer != null) {
                    this.signerHandlers.add(signer);
                }
            }

        }
    }
}
